package com.jackrain.nea.shiro.stateless;


import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SubjectFactory;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSessionStorageEvaluator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by Lucky dog on 2016/7/18.
 */
@Configuration
@Slf4j
public class ShiroConfigStateless {

    //filter 过滤
    private final String filter="/third/api/**";


    /**
     * 注册DelegatingFilterProxy（Shiro）
     *
     * @param
     * @return
     * @author SHANHY
     * @create  2016年1月13日
     */
    @Bean
    public FilterRegistrationBean shiroStatelessFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new ShiroStatelessFilterProxy("shiroStateless"));
        //  该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
        filterRegistration.addInitParameter("targetFilterLifecycle", "false");
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns(filter);
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
        return filterRegistration;
    }


    @Bean
    public ShiroFilterFactoryBean shiroStateless(@Qualifier("securityManagerStateless")SecurityManager securityManager,StatelessAccessControlFilter statelessAccessControlFilter) {
        final String authcFilter="/third/api/**";
        final ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterStateless();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        final Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();

        filterChainDefinitionMap.put(authcFilter, "statelessAuthc");
        final Map<String,Filter> filters = new LinkedHashMap<String,Filter>();
        filters.put("statelessAuthc",statelessAccessControlFilter);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        shiroFilterFactoryBean.setFilters(filters);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager  securityManagerStateless(@Qualifier("sessionManagerStateless")SessionManager sessionManager,
                                                               @Qualifier("subjectFactoryStateless")SubjectFactory subjectFactory,
                                                               StatelessRealm statelessRealm) {

        final DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        final DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        final DefaultWebSessionStorageEvaluator webSessionStorageEvaluator = new DefaultWebSessionStorageEvaluator();
        webSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(webSessionStorageEvaluator);

        securityManager.setSessionManager(sessionManager);
        securityManager.setSubjectDAO(subjectDAO);
        Collection<Realm> realms = new ArrayList<Realm>();
        realms.add(statelessRealm);
        securityManager.setRealms(realms);
        securityManager.setSubjectFactory(subjectFactory);

        return securityManager;
    }

    @Bean
    public DefaultSessionManager    sessionManagerStateless(){
        DefaultSessionManager sessionManager = new DefaultSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(false);
        return sessionManager;
    }

    @Bean
    public StatelessSubjectFactory subjectFactoryStateless(){

        return new StatelessSubjectFactory();
    }


    @Bean
    public StatelessAccessControlFilter statelessAccessControlFilter(){
        return new StatelessAccessControlFilter();
    }


    @Bean
    public StatelessRealm statelessRealm(StatelessCredentialsMatcher statelessCredentialsMatcher){
        StatelessRealm statelessRealm = new StatelessRealm();
        statelessRealm.setCredentialsMatcher(statelessCredentialsMatcher);
        statelessRealm.setCachingEnabled(false);
        return statelessRealm;
    }


    @Bean
    public StatelessCredentialsMatcher statelessCredentialsMatcher(){
        return new StatelessCredentialsMatcher();
    }



}
